package jee.boot.entity.bpm;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import jee.boot.common.CommonConstant;
import jee.boot.common.annotation.Transient;
import jee.boot.common.basic.AttrField;
import jee.boot.common.basic.DataEntity;
import jee.boot.common.basic.JoinTable;
import jee.boot.common.basic.ServiceException;
import jee.boot.common.properties.ProjectConfig;
import jee.boot.common.remote.RemoteEndpoint;
import jee.boot.common.utils.MapUtils;
import jee.boot.entity.auth.Account;
import jee.boot.common.standard.AccountHandler;
import jee.boot.common.utils.SpringContextHolder;
import jee.boot.common.utils.StringUtils;
import jee.boot.entity.system.SerialNumber;
import jee.boot.entity.system.SerialNumberFormat;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务表数据
 */
public class BusinessData extends DataEntity<BusinessData> {
    /**
     * 业务对象
     */
    private FormDefinition definition;
    /**
     * 业务数据
     */
    private Map<String, Object> data;
    /**
     * 业务数据
     */
    @Transient
    private List<Map<String, Object>> list;
    /**
     * 计算过程中的数据
     */
    @Transient
    private BusinessTable businessTable;
    @Transient
    private BusTableRel relation;
    /**
     * 删除使用的key
     */
    @Transient
    private String delKey;

    public BusinessData() {
    }

    public BusinessData(String id) {
        super(id);
    }

    public BusinessData(FormDefinition definition) {
        this.definition = definition;
    }

    @Override
    @JsonIgnore
    public String getGetSql() {
        StringBuilder sql = new StringBuilder();
        List<BusinessColumn> columnList = getColumnList();
        sql.append(getFindListSql());
        sql.append(" WHERE ").append(primaryKeySql(BpmConstant.BPM_DEFAULT_TABLE_ALIAS, columnList));
        return sql.toString();
    }


    @Override
    @JsonIgnore
    public String getFindListSql() {
        StringBuilder sql = new StringBuilder();
        String tableName = getBusinessTable().getName();
        List<BusinessColumn> columnList = getColumnList();
        List<JoinTable> joinTables = joinTable();
        if (columnList.isEmpty()) {
            throw new ServiceException(1203);
        }
        StringBuilder columns = new StringBuilder();
        for (BusinessColumn f : columnList) {
            if (StringUtils.equals(BpmConstant.SYS_YES, f.getCreate())) {
                if (findFieldNameInJoinTableColumns(f.getFieldName(), getRelChildren()) == null) {
                    if (StringUtils.equals(CommonConstant.AUDIT_FIELD_CREATE_BY, f.getFieldName()) || StringUtils.equals(CommonConstant.AUDIT_FIELD_UPDATE_BY, f.getFieldName())) {
                        columns.append(BpmConstant.BPM_DEFAULT_TABLE_ALIAS).append(".").append(f.getColumnName()).append(" AS ").append("\"").append(f.getFieldName()).append(".id\",");
                    } else {
                        columns.append(BpmConstant.BPM_DEFAULT_TABLE_ALIAS).append(".").append(f.getColumnName()).append(" AS ").append("\"").append(f.getFieldName()).append("\",");
                    }
                }
            }
        }
        if (!joinTables.isEmpty()) {
            for (JoinTable jt : joinTables) {
                for (AttrField f : jt.getColumns()) {
                    columns.append(f.getColumn()).append(" AS ").append("\"").append(f.getField()).append("\",");
                }
            }
        }
        sql.append("SELECT ");
        sql.append(StringUtils.removeEnd(columns.toString(), ","));
        sql.append(" FROM ").append(tableName).append(" ").append(BpmConstant.BPM_DEFAULT_TABLE_ALIAS);
        if (!joinTables.isEmpty()) {
            for (JoinTable jt : joinTables) {
                sql.append(" ").append(jt.getJoin()).append(" ").append(jt.getTableName()).append(" ").append(jt.getAlias());
                sql.append(" ON ").append(jt.getConditions());
            }
        }
        return sql.toString();
    }

    @Override
    @JsonIgnore
    public String getInsertSql() {
        StringBuilder sql = new StringBuilder();
        String tableName = getBusinessTable().getName();
        List<BusinessColumn> columnList = getColumnList();
        List<BusTableRel> mainRelList = getRelChildren();
        if (columnList.isEmpty()) {
            throw new ServiceException(1203);
        }
        StringBuilder columns = new StringBuilder();
        StringBuilder values = new StringBuilder();
        for (BusinessColumn f : columnList) {
            if (StringUtils.equals(BpmConstant.SYS_YES, f.getCreate())) {
                columns.append(f.getColumnName()).append(",");
                String fieldNameInJoinTableColumns = findFieldNameInJoinTableColumns(f.getFieldName(), mainRelList);
                if (fieldNameInJoinTableColumns == null) {
                    if (StringUtils.equals(CommonConstant.AUDIT_FIELD_CREATE_BY, f.getFieldName()) || StringUtils.equals(CommonConstant.AUDIT_FIELD_UPDATE_BY, f.getFieldName())) {
                        values.append("#{data.").append(f.getFieldName()).append(".id},");
                    } else {
                        values.append("#{data.").append(f.getFieldName()).append("},");
                    }
                } else {
                    values.append("#{data.").append(f.getFieldName() + "." + fieldNameInJoinTableColumns).append("},");
                }
            }
        }
        sql.append("INSERT INTO ").append(tableName).append(" ( ");
        sql.append(StringUtils.removeEnd(columns.toString(), ","));
        sql.append(" ) VALUES ( ");
        sql.append(StringUtils.removeEnd(values.toString(), ",")).append(")");
        return sql.toString();
    }

    /**
     * 生成批量新增sql的columns部分的片段,在dao的注解中组装成完整sql
     *
     * @return
     */
    @JsonIgnore
    public String getBatchInsertColumnsSql() {
        StringBuilder sql = new StringBuilder();
        String tableName = getBusinessTable().getName();
        List<BusinessColumn> columnList = getColumnList();
        if (columnList.isEmpty()) {
            throw new ServiceException(1203);
        }
        StringBuilder columns = new StringBuilder();
        for (BusinessColumn f : columnList) {
            if (StringUtils.equals(BpmConstant.SYS_YES, f.getCreate())) {
                columns.append(f.getColumnName()).append(",");
            }
        }
        sql.append("INSERT INTO ").append(tableName).append(" ( ");
        sql.append(StringUtils.removeEnd(columns.toString(), ","));
        sql.append(" ) VALUES  ");
        return sql.toString();
    }

    /**
     * 生成批量新增sql的values部分的片段,在dao的注解中组装成完整sql
     *
     * @return
     */
    @JsonIgnore
    public String getBatchInsertValuesSql() {
        List<BusinessColumn> columnList = getColumnList();
        List<BusTableRel> mainRelList = getRelChildren();
        if (columnList.isEmpty()) {
            throw new ServiceException(1203);
        }
        StringBuilder values = new StringBuilder();
        for (BusinessColumn f : columnList) {
            if (StringUtils.equals(BpmConstant.SYS_YES, f.getCreate())) {
                String fieldNameInJoinTableColumns = findFieldNameInJoinTableColumns(f.getFieldName(), mainRelList);
                if (fieldNameInJoinTableColumns == null) {
                    if (StringUtils.equals(CommonConstant.AUDIT_FIELD_CREATE_BY, f.getFieldName()) || StringUtils.equals(CommonConstant.AUDIT_FIELD_UPDATE_BY, f.getFieldName())) {
                        values.append("#{entity.data.").append(f.getFieldName()).append(".id},");
                    } else {
                        values.append("#{entity.data.").append(f.getFieldName()).append("},");
                    }
                } else {
                    values.append("#{entity.data.").append(f.getFieldName() + "." + fieldNameInJoinTableColumns).append("},");
                }
            }
        }
        return StringUtils.removeEnd(values.toString(), ",");
    }


    @Override
    @JsonIgnore
    public String getUpdateSql() {
        StringBuilder sql = new StringBuilder();
        String tableName = getBusinessTable().getName();
        List<BusinessColumn> columnList = getColumnList();
        List<BusTableRel> mainRelList = getRelChildren();
        if (columnList.isEmpty()) {
            throw new ServiceException(1203);
        }
        StringBuilder columns = new StringBuilder();
        for (BusinessColumn f : columnList) {
            if (StringUtils.equals(BpmConstant.SYS_YES, f.getCreate())) {
                String fieldNameInJoinTableColumns = findFieldNameInJoinTableColumns(f.getFieldName(), mainRelList);
                if (fieldNameInJoinTableColumns == null) {
                    if (StringUtils.equals(CommonConstant.AUDIT_FIELD_CREATE_BY, f.getFieldName()) || StringUtils.equals(CommonConstant.AUDIT_FIELD_UPDATE_BY, f.getFieldName())) {
                        columns.append(f.getColumnName()).append(" = ").append("#{data.").append(f.getFieldName()).append(".id},");
                    } else {
                        columns.append(f.getColumnName()).append(" = ").append("#{data.").append(f.getFieldName()).append("},");
                    }
                } else {
                    columns.append(f.getColumnName()).append(" = ").append("#{data.").append(f.getFieldName() + "." + fieldNameInJoinTableColumns).append("},");
                }
            }
        }
        sql.append("UPDATE ").append(tableName).append(" ").append(BpmConstant.BPM_DEFAULT_TABLE_ALIAS).append(" SET ");
        sql.append(StringUtils.removeEnd(columns.toString(), ","));
        sql.append(" WHERE ").append(primaryKeySql(BpmConstant.BPM_DEFAULT_TABLE_ALIAS, columnList));
        return sql.toString();
    }

    @Override
    @JsonIgnore
    public String getDeleteSql() {
        String tableName = getBusinessTable().getName();
        List<BusinessColumn> columnList = getColumnList();
        StringBuilder sql = new StringBuilder();
        sql.append("DELETE FROM ").append(tableName);
        // 删除sql不允许使用别名
        sql.append(" WHERE ").append(primaryKeySql(null, columnList));
        return sql.toString();
    }

    /**
     * 按条件删除
     *
     * @return
     */
    @JsonIgnore
    public String getDeleteByFilterSql() {
        String tableName = getBusinessTable().getName();
        StringBuilder sql = new StringBuilder();
        sql.append("DELETE FROM ").append(tableName).append(" WHERE ").append(getDelKey());
        return sql.toString();
    }

    /**
     * 根据主键字段拼接过滤sql
     *
     * @param alias
     * @param list
     * @return
     */
    private String primaryKeySql(String alias, List<BusinessColumn> list) {
        StringBuilder sb = new StringBuilder();
        if (list != null && !list.isEmpty()) {
            List<BusinessColumn> pkList = list.stream().filter(column -> StringUtils.equals(BpmConstant.SYS_YES, column.getPrimaryKey())).collect(Collectors.toList());
            if (pkList != null && !pkList.isEmpty()) {
                for (BusinessColumn column : pkList) {
                    if (alias != null) {
                        sb.append(alias).append(".");
                    }
                    sb.append(column.getColumnName()).append(" = ").append("#{data.").append(column.getFieldName()).append("} and");
                }
            }
        }
        if (StringUtils.isNotBlank(sb.toString())) {
            return StringUtils.removeEnd(sb.toString(), "and");
        } else {
            return alias + ".id= #{" + getId() + "}";
        }
    }

    /**
     * 获取主表关系
     *
     * @return
     */
    @JsonIgnore
    public List<BusTableRel> getRelChildren() {
        List<BusTableRel> children = getRelation().getChildren();
        return children;
    }


    /**
     * 获取主表关系
     *
     * @return
     */
    public List<BusTableRel> getRelChildren(BusTableRel relation, String type) {
        List<BusTableRel> retList = Lists.newArrayList();
        List<BusTableRel> mainRelList = relation.getChildren();
        if (mainRelList != null && !mainRelList.isEmpty()) {
            for (BusTableRel rel : mainRelList) {
                if (StringUtils.equals(rel.getType(), type)) {
                    retList.add(rel);
                }
            }
        }
        return retList;
    }

    /**
     * 主表字段
     *
     * @return
     */
    @JsonIgnore
    public List<BusinessColumn> getColumnList() {
        return getBusinessTable().coverColumnList();
    }


    /**
     * 重载关联表查询,关联表中只对一对一的进行管理,一对多的不关联
     *
     * @return
     */
    @Override
    public List<JoinTable> joinTable() {
        List<JoinTable> joinTableList = Lists.newArrayList();
        // 主表关系,忽略
        BusTableRel relation = getRelation();
        BusinessTable businessTable = getBusinessTable();
        // 子表关系
        List<BusTableRel> children = getRelChildren(relation, BpmConstant.BPM_BUSINESS_TABLE_REL_TYPE_ONE_TO_ONE);
        for (BusTableRel rel : children) {
            // 如果是一对一关系,则设置为joinTable
            addToJoinTable(joinTableList, rel, businessTable.coverColumnList(), "a", 1, null);
        }
        // 增加设计字段(创建人,修改人的关联关系)
        JoinTable createBy = new JoinTable();
        createBy.setAlias("createBy");
        createBy.setTableName("at_account");
        createBy.setFkAlias("create_by");
        createBy.getColumns().add(new AttrField("createBy.name", "createBy.name", null));
        createBy.setConditions(BpmConstant.BPM_DEFAULT_TABLE_ALIAS + ".create_by=createBy.id");
        joinTableList.add(createBy);
        // 增加设计字段(创建人,修改人的关联关系)
        JoinTable updateBy = new JoinTable();
        updateBy.setAlias("updateBy");
        updateBy.setTableName("at_account");
        updateBy.setFkAlias("update_by");
        updateBy.getColumns().add(new AttrField("updateBy.name", "updateBy.name", null));
        updateBy.setConditions(BpmConstant.BPM_DEFAULT_TABLE_ALIAS + ".update_by=updateBy.id");
        joinTableList.add(updateBy);
        return joinTableList;
    }

    /**
     * 添加到关联查询中
     *
     * @param joinTableList
     * @param rel              关系数据
     * @param parentColumnList
     * @param preAlias         主表的别名
     * @param i                递归的层级
     * @param preField         关联表中被查询出来的字段使用的属性前缀
     */
    private void addToJoinTable(List<JoinTable> joinTableList, BusTableRel rel, List<BusinessColumn> parentColumnList, String preAlias, int i, String preField) {
        // 关联的主表
        BusinessTable joinTable = rel.getBusinessTable();
        // 外键关系
        List<BusTableRelFk> fks = rel.getFks();
        // 关联表别名
        String joinTableAlias = getJoinTableAlias(/*parentColumnList,*/ fks); /*+ i*/
        ;// 这个暂时取消吧,出现多层级关联相同的表的时候在打开吧
        // 关联表名
        String joinTableName = joinTable.getName();
        // 关联表查询属性使用的完整前缀
        String fullPreField = (preField == null ? "" : preField + ".") + joinTableAlias;
        JoinTable join = createJoinTable(preAlias, joinTable, joinTableName, joinTableAlias, fks, fullPreField, rel.getChildren(),parentColumnList);
        if (join != null) {
            joinTableList.add(join);
        }
        // 下级子表关系
        List<BusTableRel> children = getRelChildren(rel, BpmConstant.BPM_BUSINESS_TABLE_REL_TYPE_ONE_TO_ONE);
        if (children != null && !children.isEmpty()) {
            i++;
            for (BusTableRel _rel : children) {
                // 如果是一对一关系,则设置为joinTable
                addToJoinTable(joinTableList, _rel, joinTable.coverColumnList(), joinTableAlias, i, fullPreField);
            }
        }
    }

    /**
     * 根据关联关系,获取关联表的别名
     *
     * @param fks
     * @return
     */
    public String getJoinTableAlias(/*List<BusinessColumn> columns,*/ List<BusTableRelFk> fks) {
        if (fks != null && !fks.isEmpty()) {
            for (BusTableRelFk fk : fks) {
                if (StringUtils.equals(fk.getType(), BpmConstant.BPM_BUSINESS_TABLE_REL_FK_TYPE_MAIN_FK)) {
                    /*return getFieldNameByColumn(columns, fk.getParentKey());*/
                    return fk.getParentKey();
                }
            }
        }
        return null;
    }

    /**
     * 如果是一对一关系,则通过外键关系找出子表中的关联属性
     *
     * @param fieldName
     * @param relList
     * @return
     */
    private String findFieldNameInJoinTableColumns(String fieldName, List<BusTableRel> relList) {
        if (relList != null && !relList.isEmpty()) {
//            boolean isOneToOne = false;
//            List<BusinessColumn> columnList = null;
            for (BusTableRel rel : relList) {
                List<BusTableRelFk> fks = rel.getFks();
                if (StringUtils.equals(rel.getType(), BpmConstant.BPM_BUSINESS_TABLE_REL_TYPE_ONE_TO_ONE)) {
//                    String joinTableKey = null;
                    for (BusTableRelFk fk : fks) {
                        // 一对一关系
                        if (StringUtils.equals(fk.getParentKey(), fieldName)) {
//                            isOneToOne = true;
//                            joinTableKey = fk.getJoinTableKey();
//                            columnList = rel.getBusinessTable().coverColumnList();
                            return fk.getJoinTableKey();
                        }
                    }
//                    if (isOneToOne) {
//                        for (BusinessColumn c : columnList) {
//                            if (StringUtils.equals(c.getColumnName(), joinTableKey)) {
//                                return c.getFieldName();
//                            }
//                        }
//                    }
                }

            }
        }
        return null;
    }

    /**
     * 生成一个关联表
     *
     * @param preAlias       关联主表的别名
     * @param joinTable      被关联的表对象
     * @param joinTableName  被关联的表名
     * @param joinTableAlias 被关联的表别名
     * @param fks            关联关系
     * @param fullPreField   完整的属性前缀
     * @param children
     * @param parentColumnList
     * @return
     */
    private JoinTable createJoinTable(String preAlias, BusinessTable joinTable, String joinTableName, String joinTableAlias, List<BusTableRelFk> fks, String fullPreField, List<BusTableRel> children, List<BusinessColumn> parentColumnList) {
        if (fks != null && !fks.isEmpty()) {
            JoinTable join = new JoinTable();
            join.setTableName(joinTableName);
            join.setAlias(joinTableAlias);
            join.setFkAlias(preAlias);
            List<String> on = Lists.newArrayList();
            for (BusTableRelFk fk : fks) {
                switch (fk.getType()) {
                    // 外键关联
                    case BpmConstant.BPM_BUSINESS_TABLE_REL_FK_TYPE_MAIN_FK:
                        on.add(getColumnByFieldName(joinTableAlias, joinTable.coverColumnList(), fk.getJoinTableKey())
                                + "=" +
                                getColumnByFieldName(preAlias, parentColumnList, fk.getParentKey()));
                        break;
                    //固定值
                    case BpmConstant.BPM_BUSINESS_TABLE_REL_FK_TYPE_FIXED_VALUE:
                        on.add(getColumnByFieldName(joinTableAlias, joinTable.coverColumnList(), fk.getJoinTableKey()) + "='" + fk.getParentKey() + "'");
                        break;
                }
            }
            join.setConditions(StringUtils.join(on, " and "));

            List<BusinessColumn> columns = joinTable.coverColumnList();
            // 开始设置关联表中需要被查询出来的字段,默认查询所有字段吧
            for (BusinessColumn column : columns) {
                if (StringUtils.equals(BpmConstant.SYS_YES, column.getCreate())) {
                    if (findFieldNameInJoinTableColumns(column.getColumnName(), children) == null) {
                        String columnName = joinTableAlias + "." + column.getColumnName();
                        String fieldName = fullPreField + "." + column.getFieldName();
                        join.getColumns().add(new AttrField(fieldName, columnName, null));
                    }
                }
            }
            return join;
        }
        return null;
    }

    @Override
    public void preInsert() {
        super.preInsert();
        // 设置主键以及审计字段
        overrideDefaultPreInsert();
    }


    @Override
    public void preUpdate() {
        super.preUpdate();
        // 设置主键以及审计字段
        overrideDefaultPreUpdate();
    }


    /**
     * 覆盖默认的PreInsert中的方法
     */
    private void overrideDefaultPreInsert() {
        List<BusinessColumn> mainColumnList = getColumnList();
        for (BusinessColumn column : mainColumnList) {
            if (data != null) {
                if (StringUtils.equalsIgnoreCase("id", column.getFieldName()) && StringUtils.equals(column.getPrimaryKey(), BpmConstant.SYS_YES)) {
                    // 如果该字段为主键,并且名称是id,则生成32长度的uuid
                    data.put(column.getFieldName(), getId());
                }
                // 日期类型 需要将数据有long转换为Date
                if (StringUtils.equals(BpmConstant.BPM_COLUMN_DATA_TYPE_DATE, column.getDataType())) {
                    if (data.containsKey(column.getFieldName()) && data.get(column.getFieldName()) instanceof Long) {
                        long o = (long) data.get(column.getFieldName());
                        Date date = new Date(o);
                        data.put(column.getFieldName(), date);
                    }
                }
                // 自动生成序列号
                if(StringUtils.equals(BpmConstant.BPM_CONTROL_TYPE_SERIAL, column.getControlType())){
                    RemoteEndpoint remoteEndpoint = SpringContextHolder.getApplicationContext().getBean(RemoteEndpoint.class);
                    ProjectConfig projectConfig = SpringContextHolder.getApplicationContext().getBean(ProjectConfig.class);
                    SerialNumber serialNumber=new SerialNumber();
                    Map<String, Object> setting = column.getSetting();
                    serialNumber.setSerialNumberFormat(new SerialNumberFormat(MapUtils.getValue(setting,"id")));
                    serialNumber.setType(getTableName());
                    serialNumber.setCategory(column.getFieldName());
                    SerialNumber sn = remoteEndpoint.executePost(projectConfig.getOpenSystemServer(), "/serial/newSerial", serialNumber, SerialNumber.class);
                    data.put(column.getFieldName(), sn.getSerialNumber());

                }
            }
        }
        // 审计字段
        Account account = SpringContextHolder.getApplicationContext().getBean(AccountHandler.class).getPrincipal();
        if (account != null) {
            data.put(CommonConstant.AUDIT_FIELD_CREATE_BY, account.shortInfo());
            data.put(CommonConstant.AUDIT_FIELD_UPDATE_BY, account.shortInfo());
        }
        Date now = new Date();
        data.put(CommonConstant.AUDIT_FIELD_CREATE_DATE, now);
        data.put(CommonConstant.AUDIT_FIELD_UPDATE_DATE, now);
        if (!data.containsKey(CommonConstant.AUDIT_FIELD_STATUS) || StringUtils.isBlank(data.get(CommonConstant.AUDIT_FIELD_STATUS).toString())) {
            data.put(CommonConstant.AUDIT_FIELD_STATUS, CommonConstant.DATA_STATUS_ACTIVE);
        }
    }

    /**
     * 覆盖默认的PreUpdate中的方法
     */
    private void overrideDefaultPreUpdate() {
        List<BusinessColumn> mainColumnList = getColumnList();
        // 审计字段
        Account account = SpringContextHolder.getApplicationContext().getBean(AccountHandler.class).getPrincipal();
        if (account != null) {
            data.put(CommonConstant.AUDIT_FIELD_UPDATE_BY, account.shortInfo());
        }
        Date now = new Date();
        data.put(CommonConstant.AUDIT_FIELD_UPDATE_DATE, now);
        for (BusinessColumn column : mainColumnList) {
            if (data != null) {
                // 日期类型 需要将数据有long转换为Date
                if (StringUtils.equals(BpmConstant.BPM_COLUMN_DATA_TYPE_DATE, column.getDataType())) {
                    if (data.containsKey(column.getFieldName()) && data.get(column.getFieldName()) instanceof Long) {
                        long o = (long) data.get(column.getFieldName());
                        Date date = new Date(o);
                        data.put(column.getFieldName(), date);
                    }
                }
            }
        }
    }

    /**
     * 配置计算过程中要用的数据
     */
    public void configDefinition(FormDefinition definition) {
        if (definition != null) {
            setDefinition(definition);
            setRelation(definition.getBusinessObject().getRelation());
            setBusinessTable(getRelation().getBusinessTable());
        }
    }

    /**
     * 配置计算过程中要用的数据
     */
    public void configDefinition(BusTableRel relation) {
        if (relation != null) {
            setRelation(relation);
            setBusinessTable(relation.getBusinessTable());
        }
    }

    @Override
    public String getColumnByFieldName(String fieldName) {
        List<BusinessColumn> columnList = getColumnList();
        return getColumnByFieldName(BpmConstant.BPM_DEFAULT_TABLE_ALIAS, columnList, fieldName);
    }

    public String getColumnByFieldName(String alias, List<BusinessColumn> columnList, String fieldName) {
        for (BusinessColumn column : columnList) {
            if (StringUtils.equals(fieldName, column.getFieldName())) {
                return alias + "." + column.getColumnName();
            }
        }
        // 如果没有找到属性,则按驼峰转换该属性,如果属性中包含.,则转换最后一个小数点后面的部分
        return turnUnderline(fieldName);

    }

    public String getFieldNameByColumn(String columnName) {
        List<BusinessColumn> columnList = getColumnList();
        return getFieldNameByColumn(columnList, columnName);
    }

    public String getFieldNameByColumn(List<BusinessColumn> columnList, String columnName) {
        for (BusinessColumn column : columnList) {
            if (StringUtils.equals(columnName, column.getColumnName())) {
                return column.getFieldName();
            }
        }
        return null;
    }

    /**
     * 获取主键
     *
     * @return
     */
    @JsonIgnore
    public String getPrimaryKey() {
        List<BusinessColumn> columnList = getColumnList();
        List<String> pkList = columnList.stream().filter(column -> StringUtils.equals(BpmConstant.SYS_YES, column.getPrimaryKey())).map(column -> column.getFieldName()).collect(Collectors.toList());
        if (pkList != null && !pkList.isEmpty() && data != null) {
            // 排序下,统一联合主键拼接生成的主键字符串
            Collections.sort(pkList);
            StringBuilder pkString = new StringBuilder();
            for (String pk : pkList) {
                Object o = data.get(pk);
                if (o != null && StringUtils.isNotBlank(o.toString())) {
                    pkString.append(o);
                }
            }
            return pkString.toString();
        }
        return getId();
    }

    /**
     * 是否包含附件,如果包含,则返回附件字段
     *
     * @return
     */
    public List<BusinessColumn> attachmentFields() {
        List<BusinessColumn> columnList = getColumnList();
        List<BusinessColumn> collect = columnList.stream().filter(column -> StringUtils.equals(BpmConstant.BPM_COLUMN_DATA_TYPE_FILE, column.getDataType())).collect(Collectors.toList());
        if (collect != null && !collect.isEmpty()) {
            return collect;
        }
        return Lists.newArrayList();
    }

    @Override
    public String getTableName() {
        if(businessTable!=null){
            return businessTable.getTableName();
        }
        return super.getTableName();
    }

    // -------------------------------------------------------------------------------------------
    public FormDefinition getDefinition() {
        return definition;
    }

    public void setDefinition(FormDefinition definition) {
        this.definition = definition;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }

    public List<Map<String, Object>> getList() {
        return list;
    }

    public void setList(List<Map<String, Object>> list) {
        this.list = list;
    }

    public BusinessTable getBusinessTable() {
        return businessTable;
    }

    public void setBusinessTable(BusinessTable businessTable) {
        this.businessTable = businessTable;
    }

    public BusTableRel getRelation() {
        return relation;
    }

    public void setRelation(BusTableRel relation) {
        this.relation = relation;
    }

    public String getDelKey() {
        return delKey;
    }

    public void setDelKey(String delKey) {
        this.delKey = delKey;
    }
}
